package com.resou.reader.bookshelf;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.resou.reader.ACache;
import com.resou.reader.ReSouApplication;
import com.resou.reader.api.entry.Result;
import com.resou.reader.base.ResouBasePresenter;
import com.resou.reader.bookshelf.readhistory.datasupport.BookCollection;
import com.resou.reader.data.Injection;
import com.resou.reader.data.bookshelf.BookshelfRepository;
import com.resou.reader.data.bookshelf.model.ScrollNotice;
import com.resou.reader.data.local.LitePalHelper;
import com.resou.reader.data.readhistory.ReadHistoryRepository;
import com.resou.reader.data.signin.SignInRepository;
import com.resou.reader.data.signin.model.SignStatus;
import com.resou.reader.mine.IView.UserInstance;
import com.resou.reader.utils.AppExecutors;
import com.resou.reader.utils.ToastUtil;
import com.resou.reader.utils.UserUtil;
import com.resou.reader.utils.eventbus.LoadBookEvent;

import org.greenrobot.eventbus.EventBus;
import org.litepal.LitePal;

import java.io.File;
import java.io.IOException;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Call;
import retrofit2.Response;

public class HomeBookShelfPresenter extends ResouBasePresenter<HomeBookShelfContract.HomeBookShelfView> implements HomeBookShelfContract.HomeBoolShelfPresenter {
    private final BookshelfRepository mRepository;
    private final SignInRepository mSignInRepository;
    private static final String TAG = "HomeBookShelfFragment";

    //缓存文件
    private File file;

    private ACache cache;

    public HomeBookShelfPresenter(HomeBookShelfContract.HomeBookShelfView view) {
        super(view);
        mRepository = Injection.provideBookshelfRepository();
        mSignInRepository = Injection.provideSignInRepository();
        file = new File(mView.getViewContext().getCacheDir(), "bookcover");
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 删除书籍
     */
    public void deleteBook(String bookId) {
        addCompositeDisposable(
                Observable.create((ObservableOnSubscribe<Boolean>) emitter -> {
                    //删除本地书籍
                    LitePal.deleteAll(BookCollection.class, "bookId = ?", bookId);
                    emitter.onNext(true);
                })
                        .subscribeOn(getIOSchedulers())
                        .observeOn(getMainSchedulers())
                        .subscribe(result -> {
                            mView.deleteItem(bookId);
                            ToastUtil.makeShortToast("删除成功");
                        }, throwable -> {
                            ToastUtil.makeShortToast("删除失败");
                        })
        );
        addCompositeDisposable(
                mRepository.deleteBook(UserInstance.getToken(), bookId)
                        .subscribeOn(getIOSchedulers())
                        .observeOn(getIOSchedulers())
                        .subscribe(result -> {
                        }, throwable -> {
                        })
        );
    }

    /**
     * 更新签到信息
     */
    public void updateSignInfo() {
        String token = UserUtil.getToken();
        if (TextUtils.isEmpty(token)) {
            return;
        }
        addCompositeDisposable(
                mSignInRepository.checkIsSignedIn(token)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(result -> {
                            if (result.getCode() == 0) {
                                SignStatus data = result.getData();
                                mView.showSignStatus(data);
                            }
                        }, throwable -> {
                            Log.d(TAG, "updateSignInfo: " + throwable.getMessage());
                        })
        );
    }

    /**
     * 获取滚动公告栏
     */
    public void getScrollBulletinBoard(String token) {
        addCompositeDisposable(
                mRepository.getScrollBulletinBoard(token)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(scrollNoticeResult -> {
                            if (scrollNoticeResult.getCode() == 0) {
                                List<ScrollNotice> data = scrollNoticeResult.getData();
                                mView.setScrollBoardInfo(data);
                            }
                        }, throwable -> {
                            Log.i(TAG, "getScrollBulletinBoard: " + throwable.getMessage());
                        })
        );
    }

    /**
     * 异步同步书籍
     *
     * @param bookIdStr
     */
    public synchronized void synchronizeBooks(String bookIdStr) {
        mRepository.synchronizeBooks(UserInstance.getToken(), bookIdStr, "android")
                .subscribeOn(getIOSchedulers())
                .observeOn(getMainSchedulers())
                .subscribe(new DefaultObserver<List<BookCollection>>() {
                    @Override
                    public void onNext(List<BookCollection> bookCollections) {
                        LitePalHelper.loadLocalLitePal(bookCollections);
                        mView.showContent(bookCollections);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }

    /**
     * 加载服务端书籍
     */
    public synchronized void loadRemoteBooks(int page, int pagesize) {
        Log.i(TAG, "loadRemoteBooks: 加载服务器");
        mRepository.getBooks(UserInstance.getToken(), page, pagesize)
                .subscribeOn(getIOSchedulers())
                .observeOn(getMainSchedulers())
                .subscribe(new Observer<List<BookCollection>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addCompositeDisposable(d);
                    }

                    @Override
                    public void onNext(List<BookCollection> list) {
                        if (list.size() > 0) {
                            if (page == 0) {
                                quearCover();
                                mView.getSmartRefreshLayout().finishRefresh();
                                mView.getAdapter().loadMoreComplete();
                            }
                            if (list.size() < pagesize) {
                                mView.getAdapter().loadMoreEnd();
                            } else {
                                mView.getAdapter().loadMoreComplete();
                            }
                            mView.showContent(list);
                        } else {
                            if (page == 0) {
                                mView.showContent(list);
                            }
                            mView.getSmartRefreshLayout().finishRefresh();
                            mView.getAdapter().loadMoreEnd();
                        }

                        LitePalHelper.loadLocalLitePal(list);
                    }

                    @Override
                    public void onError(Throwable e) {
                        mView.finishRefresh();
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 获取封面
     */
    public void quearCover() {
        mRepository.getBooksCover()
                .subscribeOn(getIOSchedulers())
                .observeOn(getMainSchedulers())
                .subscribe(new Consumer<BookCollection>() {
                    @Override
                    public void accept(BookCollection bookCollection) throws Exception {
                        mView.setBookCover(bookCollection);
                        ACache.get(file).put("bookcover", ReSouApplication.gson.toJson(bookCollection));
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        mView.setBookCover(null);
                    }
                });
    }

    /**
     * 获取书架列表
     */
    public void requestPursuitBookList() {
        addCompositeDisposable(
                Observable.create((ObservableOnSubscribe<List<BookCollection>>) emitter -> {
                    List<BookCollection> list = LitePalHelper.loadShelfBooks();
                    emitter.onNext(list);
                })
                        .subscribeOn(getIOSchedulers())
                        .observeOn(getMainSchedulers())
                        .subscribe(bookCollections -> {
                            if (bookCollections != null) {
                                mView.showContent(bookCollections);
                            }
                            String chapterItemJson = ACache.get(file).getAsString("bookcover");
                            BookCollection bookCollection = ReSouApplication.gson.fromJson(chapterItemJson, BookCollection.class);
                            mView.setBookCover(bookCollection);
                            mView.finishRefresh();
                        }, throwable -> {
                            mView.finishRefresh();
                        })
        );
    }


    /**
     * 更新查看时间
     */
    public void updataLookTime(BookCollection book) {
        AppExecutors.getAppExecutors().networkIO().execute(() -> {
            ReadHistoryRepository historyRepository = ReadHistoryRepository.getInstance();
            if (book != null) {
                Call<Result> resultCall = historyRepository.uploadReadingRecord(UserInstance.getToken(), book.getBookId(), book.getHistoryChapterId());
                try {
                    Response<Result> response = resultCall.execute();
                    if (response.isSuccessful()) {
                        EventBus.getDefault().post(new LoadBookEvent(false));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }


}
